home *** CD-ROM | disk | FTP | other *** search
/ Acorn RISC PD-CD 1 / Acorn RISC PD-CD 1.iso / languages / gawk / h / awk next >
Encoding:
Text File  |  1990-09-21  |  13.8 KB  |  501 lines

  1. /*
  2.  * awk.h -- Definitions for gawk. 
  3.  */
  4.  
  5. /* 
  6.  * Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
  7.  * 
  8.  * This file is part of GAWK, the GNU implementation of the
  9.  * AWK Progamming Language.
  10.  * 
  11.  * GAWK is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 1, or (at your option)
  14.  * any later version.
  15.  * 
  16.  * GAWK is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  * 
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with GAWK; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25.  
  26. /* ------------------------------ Includes ------------------------------ */
  27. #include <math.h>
  28. #include <time.h>
  29. #include <stdio.h>
  30. #include <ctype.h>
  31. #include <errno.h>
  32. #include <stddef.h>
  33. #include <stdlib.h>
  34. #include <setjmp.h>
  35. #include <stdarg.h>
  36. #include <string.h>
  37.  
  38. #include "regex.h"
  39.  
  40. /* ------------------- System Functions, Variables, etc ------------------- */
  41. #define unlink(name)    remove(name)
  42.  
  43. extern int strnlcmp (const char *s, const char *t, int n);
  44. extern void *alloca (size_t size);
  45. extern FILE *popen (char *command, char *mode);
  46. extern int pclose (FILE *fd);
  47. extern int  getopt (int argc, char *argv[], const char *optstring);
  48. extern char *optarg;
  49. extern int  optind;
  50. extern int  opterr;
  51. extern char *temp_dir;
  52. extern char *mktemp (const char *file);
  53. extern char *dirscan (const char *file);
  54.  
  55. /* ------------------ Constants, Structures, Typedefs  ------------------ */
  56. #define AWKNUM    double
  57.  
  58. typedef enum {
  59.     /* illegal entry == 0 */
  60.     Node_illegal,
  61.  
  62.     /* binary operators  lnode and rnode are the expressions to work on */
  63.     Node_times,
  64.     Node_quotient,
  65.     Node_mod,
  66.     Node_plus,
  67.     Node_minus,
  68.     Node_cond_pair,        /* conditional pair (see Node_line_range) */
  69.     Node_subscript,
  70.     Node_concat,
  71.     Node_exp,
  72.  
  73.     /* unary operators   subnode is the expression to work on */
  74. /*10*/    Node_preincrement,
  75.     Node_predecrement,
  76.     Node_postincrement,
  77.     Node_postdecrement,
  78.     Node_unary_minus,
  79.     Node_field_spec,
  80.  
  81.     /* assignments   lnode is the var to assign to, rnode is the exp */
  82.     Node_assign,
  83.     Node_assign_times,
  84.     Node_assign_quotient,
  85.     Node_assign_mod,
  86. /*20*/    Node_assign_plus,
  87.     Node_assign_minus,
  88.     Node_assign_exp,
  89.  
  90.     /* boolean binaries   lnode and rnode are expressions */
  91.     Node_and,
  92.     Node_or,
  93.  
  94.     /* binary relationals   compares lnode and rnode */
  95.     Node_equal,
  96.     Node_notequal,
  97.     Node_less,
  98.     Node_greater,
  99.     Node_leq,
  100. /*30*/    Node_geq,
  101.     Node_match,
  102.     Node_nomatch,
  103.  
  104.     /* unary relationals   works on subnode */
  105.     Node_not,
  106.  
  107.     /* program structures */
  108.     Node_rule_list,        /* lnode is a rule, rnode is rest of list */
  109.     Node_rule_node,        /* lnode is pattern, rnode is statement */
  110.     Node_statement_list,    /* lnode is statement, rnode is more list */
  111.     Node_if_branches,    /* lnode is to run on true, rnode on false */
  112.     Node_expression_list,    /* lnode is an exp, rnode is more list */
  113.     Node_param_list,    /* lnode is a variable, rnode is more list */
  114.  
  115.     /* keywords */
  116. /*40*/    Node_K_if,        /* lnode is conditonal, rnode is if_branches */
  117.     Node_K_while,        /* lnode is condtional, rnode is stuff to run */
  118.     Node_K_for,        /* lnode is for_struct, rnode is stuff to run */
  119.     Node_K_arrayfor,    /* lnode is for_struct, rnode is stuff to run */
  120.     Node_K_break,        /* no subs */
  121.     Node_K_continue,    /* no stuff */
  122.     Node_K_print,        /* lnode is exp_list, rnode is redirect */
  123.     Node_K_printf,        /* lnode is exp_list, rnode is redirect */
  124.     Node_K_next,        /* no subs */
  125.     Node_K_exit,        /* subnode is return value, or NULL */
  126.     Node_K_do,        /* lnode is conditional, rnode stuff to run */
  127.     Node_K_return,
  128.     Node_K_delete,
  129.     Node_K_getline,
  130.     Node_K_function,    /* lnode is statement list, rnode is params */
  131.  
  132.     /* I/O redirection for print statements */
  133.     Node_redirect_output,    /* subnode is where to redirect */
  134.     Node_redirect_append,    /* subnode is where to redirect */
  135.     Node_redirect_pipe,    /* subnode is where to redirect */
  136.     Node_redirect_pipein,    /* subnode is where to redirect */
  137.     Node_redirect_input,    /* subnode is where to redirect */
  138.  
  139.     /* Variables */
  140.     Node_var,        /* rnode is value, lnode is array stuff */
  141.     Node_var_array,        /* array is ptr to elements, asize num of
  142.                  * eles */
  143.     Node_val,        /* node is a value - type in flags */
  144.  
  145.     /* Builtins   subnode is explist to work on, proc is func to call */
  146.     Node_builtin,
  147.  
  148.     /*
  149.      * pattern: conditional ',' conditional ;  lnode of Node_line_range
  150.      * is the two conditionals (Node_cond_pair), other word (rnode place)
  151.      * is a flag indicating whether or not this range has been entered.
  152.      */
  153.     Node_line_range,
  154.  
  155.     /*
  156.      * boolean test of membership in array lnode is string-valued
  157.      * expression rnode is array name 
  158.      */
  159.     Node_in_array,
  160.  
  161.     Node_func,        /* lnode is param. list, rnode is body */
  162.     Node_func_call,        /* lnode is name, rnode is argument list */
  163.  
  164.     Node_cond_exp,        /* lnode is conditonal, rnode is if_branches */
  165.     Node_regex,
  166.     Node_hashnode,
  167.     Node_ahash
  168. } NODETYPE;
  169.  
  170. /*
  171.  * NOTE - this struct is a rather kludgey -- it is packed to minimize
  172.  * space usage, at the expense of cleanliness.  Alter at own risk.
  173.  */
  174. typedef struct exp_node {
  175.     union {
  176.         struct {
  177.             union {
  178.                 struct exp_node *lptr;
  179.                 char *param_name;
  180.                 char *retext;
  181.                 struct exp_node *nextnode;
  182.             } l;
  183.             union {
  184.                 struct exp_node *rptr;
  185.                 struct exp_node *(*pptr) ();
  186.                 struct re_pattern_buffer *preg;
  187.                 struct for_loop_header *hd;
  188.                 struct exp_node **av;
  189.                 int r_ent;    /* range entered */
  190.             } r;
  191.             char *name;
  192.             short number;
  193.             unsigned char recase;
  194.         } nodep;
  195.         struct {
  196.             AWKNUM fltnum;    /* this is here for optimal packing of
  197.                      * the structure on many machines
  198.                      */
  199.             char *sp;
  200.             short slen;
  201.             unsigned char sref;
  202.         } val;
  203.         struct {
  204.             struct exp_node *next;
  205.             char *name;
  206.             int length;
  207.             struct exp_node *value;
  208.         } hash;
  209. #define    hnext    sub.hash.next
  210. #define    hname    sub.hash.name
  211. #define    hlength    sub.hash.length
  212. #define    hvalue    sub.hash.value
  213.         struct {
  214.             struct exp_node *next;
  215.             struct exp_node *name;
  216.             struct exp_node *value;
  217.         } ahash;
  218. #define    ahnext    sub.ahash.next
  219. #define    ahname    sub.ahash.name
  220. #define    ahvalue    sub.ahash.value
  221.     } sub;
  222.     NODETYPE type;
  223.     unsigned char flags;
  224. #            define    MEM    0x7
  225. #            define    MALLOC    1    /* can be free'd */
  226. #            define    TEMP    2    /* should be free'd */
  227. #            define    PERM    4    /* can't be free'd */
  228. #            define    VAL    0x18
  229. #            define    NUM    8    /* numeric value is valid */
  230. #            define    STR    16    /* string value is valid */
  231. #            define    NUMERIC    32    /* entire field is numeric */
  232. } NODE;
  233.  
  234. #define lnode    sub.nodep.l.lptr
  235. #define nextp    sub.nodep.l.nextnode
  236. #define rnode    sub.nodep.r.rptr
  237. #define source_file    sub.nodep.name
  238. #define    source_line    sub.nodep.number
  239. #define    param_cnt    sub.nodep.number
  240. #define param    sub.nodep.l.param_name
  241.  
  242. #define subnode    lnode
  243. #define proc    sub.nodep.r.pptr
  244.  
  245. #define reexp    lnode
  246. #define rereg    sub.nodep.r.preg
  247. #define re_case sub.nodep.recase
  248. #define re_text sub.nodep.l.retext
  249.  
  250. #define forsub    lnode
  251. #define forloop    rnode->sub.nodep.r.hd
  252.  
  253. #define stptr    sub.val.sp
  254. #define stlen    sub.val.slen
  255. #define stref    sub.val.sref
  256. #define    valstat    flags
  257.  
  258. #define numbr    sub.val.fltnum
  259.  
  260. #define var_value lnode
  261. #define var_array sub.nodep.r.av
  262.  
  263. #define condpair lnode
  264. #define triggered sub.nodep.r.r_ent
  265.  
  266. #define HASHSIZE 101
  267.  
  268. typedef struct for_loop_header {
  269.     NODE *init;
  270.     NODE *cond;
  271.     NODE *incr;
  272. } FOR_LOOP_HEADER;
  273.  
  274. /* for "for(iggy in foo) {" */
  275. struct search {
  276.     int numleft;
  277.     NODE **arr_ptr;
  278.     NODE *bucket;
  279.     NODE *retval;
  280. };
  281.  
  282. /* for faster input, bypass stdio */
  283. typedef struct iobuf {
  284.     FILE *fp;
  285.     char *buf;
  286.     char *off;
  287.     int size;    /* this will be determined by an fstat() call */
  288.     int cnt;
  289.     char *secbuf;
  290.     int secsiz;
  291.     int flag;
  292. } IOBUF;
  293.  
  294. /*
  295.  * structure used to dynamically maintain a linked-list of open files/pipes
  296.  */
  297. struct redirect {
  298.     int flag;
  299. #        define        RED_FILE    1
  300. #        define        RED_PIPE    2
  301. #        define        RED_READ    4
  302. #        define        RED_WRITE    8
  303. #        define        RED_APPEND    16
  304.     char *value;
  305.     FILE *fp;
  306.     IOBUF *iop;
  307.     int pid;
  308.     int status;
  309.     long offset;        /* used for dynamic management of open files */
  310.     struct redirect *prev;
  311.     struct redirect *next;
  312. };
  313.  
  314. /* longjmp return codes, must be nonzero */
  315. /* Continue means either for loop/while continue, or next input record */
  316. #define TAG_CONTINUE 1
  317. /* Break means either for/while break, or stop reading input */
  318. #define TAG_BREAK 2
  319. /* Return means return from a function call; leave value in ret_node */
  320. #define    TAG_RETURN 3
  321.  
  322. #ifdef MSDOS
  323. #define HUGE    0x7fff
  324. #else
  325. #define HUGE    0x7fffffff
  326. #endif
  327.  
  328. /* -------------------------- External variables -------------------------- */
  329. /* gawk builtin variables */
  330. extern NODE *FS_node, *NF_node, *RS_node, *NR_node;
  331. extern NODE *FILENAME_node, *OFS_node, *ORS_node, *OFMT_node;
  332. extern NODE *FNR_node, *RLENGTH_node, *RSTART_node, *SUBSEP_node;
  333. extern NODE *IGNORECASE_node;
  334.  
  335. extern NODE **stack_ptr;
  336. extern NODE *Nnull_string;
  337. extern NODE *deref;
  338. extern NODE **fields_arr;
  339. extern int sourceline;
  340. extern char *source;
  341. extern NODE *expression_value;
  342.  
  343. extern NODE *variables[];
  344.  
  345. extern NODE *_t;    /* used as temporary in tree_eval */
  346.  
  347. extern char *myname;
  348.  
  349. extern int node0_valid;
  350. extern int field_num;
  351. extern int strict;
  352.  
  353. /* ------------------------- Pseudo-functions ------------------------- */
  354. #define is_identchar(c) (isalnum(c) || (c) == '_')
  355.  
  356.  
  357. #define    free_temp(n)    if ((n)->flags&TEMP) { deref = (n); do_deref(); } else
  358. #define    tree_eval(t)    (_t = (t),(_t) == NULL ? Nnull_string : \
  359.             ((_t)->type == Node_val ? (_t) : r_tree_eval((_t))))
  360. #define    make_string(s,l)    make_str_node((s),(l),0)
  361.  
  362. #define    cant_happen()    fatal("line %d, file: %s; bailing out", \
  363.                 __LINE__, __FILE__);
  364. #ifdef MEMDEBUG
  365. #define memmsg(x,y,z,zz)    fprintf(stderr, "malloc: %s: %s: %d %0x\n", z, x, y, zz)
  366. #define free(s)    fprintf(stderr, "free: s: %0x\n", s), do_free(s)
  367. #else
  368. #define memmsg(x,y,z,zz)
  369. #endif
  370.  
  371. #define    emalloc(var,ty,x,str) \
  372.     if ((var = (ty) malloc((unsigned)((x)?(x):1))) == NULL) \
  373.         fatal("%s: %s: can't allocate memory (%s)", \
  374.         (str), #var, strerror(errno)); else \
  375.         memmsg(#var, x, str, var)
  376. #define    erealloc(var,ty,x,str) \
  377.     if ((var = (ty) realloc((char *)var,(unsigned)((x)?(x):1))) == NULL) \
  378.         fatal("%s: %s: can't allocate memory (%s)", \
  379.         (str), #var, strerror(errno)); else \
  380.         memmsg("re: " #var, x, str, var)
  381. #ifdef DEBUG
  382. #define    force_number    r_force_number
  383. #define    force_string    r_force_string
  384. #else
  385. #ifdef lint
  386. extern AWKNUM force_number();
  387. #endif
  388. #ifdef MSDOS
  389. extern double _msc51bug;
  390. #define    force_number(n)    (_msc51bug=(_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t)))
  391. #else
  392. #define    force_number(n)    (_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t))
  393. #endif
  394. #define    force_string(s)    (_t = (s),(_t->flags & STR) ? _t : r_force_string(_t))
  395. #endif
  396.  
  397. #define    STREQ(a,b)    (*(a) == *(b) && strcmp((a), (b)) == 0)
  398. #define    STREQN(a,b,n)    ((n) && *(a) == *(b) && strncmp((a), (b), (n)) == 0)
  399.  
  400. #define    WHOLELINE    (node0_valid ? fields_arr[0] : *get_field(0,0))
  401.  
  402. /* ------------- Function prototypes or defs (as appropriate) ------------- */
  403. #ifdef __STDC__
  404. extern    int parse_escape(char **);
  405. extern    FILE *devopen(char *, char *);
  406. extern    struct re_pattern_buffer *make_regexp(NODE *, int);
  407. extern    struct re_pattern_buffer *mk_re_parse(char *, int);
  408. extern    NODE *variable(char *);
  409. extern    NODE *install(NODE **, char *, NODE *);
  410. extern    NODE *lookup(NODE **, char *);
  411. extern    NODE *make_name(char *, NODETYPE);
  412. extern    int interpret(NODE *);
  413. extern    NODE *r_tree_eval(NODE *);
  414. extern    void assign_number(NODE **, double);
  415. extern    int cmp_nodes(NODE *, NODE *);
  416. extern    struct redirect *redirect(NODE *, int *);
  417. extern    int flush_io(void);
  418. extern    void print_simple(NODE *, FILE *);
  419. extern    void warning(char *,...);
  420. extern    void fatal(char *,...);
  421. extern    void set_record(char *, int);
  422. extern    NODE **get_field(int, int);
  423. extern    NODE **get_lhs(NODE *, int);
  424. extern    void do_deref(void );
  425. extern    struct search *assoc_scan(NODE *);
  426. extern    struct search *assoc_next(struct search *);
  427. extern    NODE **assoc_lookup(NODE *, NODE *);
  428. extern    double r_force_number(NODE *);
  429. extern    NODE *r_force_string(NODE *);
  430. extern    NODE *newnode(NODETYPE);
  431. extern    NODE *dupnode(NODE *);
  432. extern    NODE *make_number(double);
  433. extern    NODE *tmp_number(double);
  434. extern    NODE *make_str_node(char *, int, int);
  435. extern    NODE *tmp_string(char *, int);
  436. extern    char *re_compile_pattern(char *, int, struct re_pattern_buffer *);
  437. extern    int re_search(struct re_pattern_buffer *, char *, int, int, int, struct re_registers *);
  438. extern    void freenode(NODE *);
  439.  
  440. #else
  441. extern    int parse_escape();
  442. extern    void freenode();
  443. extern    int devopen();
  444. extern    struct re_pattern_buffer *make_regexp();
  445. extern    struct re_pattern_buffer *mk_re_parse();
  446. extern    NODE *variable();
  447. extern    NODE *install();
  448. extern    NODE *lookup();
  449. extern    int interpret();
  450. extern    NODE *r_tree_eval();
  451. extern    void assign_number();
  452. extern    int cmp_nodes();
  453. extern    struct redirect *redirect();
  454. extern    int flush_io();
  455. extern    void print_simple();
  456. extern    void warning();
  457. extern    void fatal();
  458. extern    void set_record();
  459. extern    NODE **get_field();
  460. extern    NODE **get_lhs();
  461. extern    void do_deref();
  462. extern    struct search *assoc_scan();
  463. extern    struct search *assoc_next();
  464. extern    NODE **assoc_lookup();
  465. extern    double r_force_number();
  466. extern    NODE *r_force_string();
  467. extern    NODE *newnode();
  468. extern    NODE *dupnode();
  469. extern    NODE *make_number();
  470. extern    NODE *tmp_number();
  471. extern    NODE *make_str_node();
  472. extern    NODE *tmp_string();
  473. extern    char *re_compile_pattern();
  474. extern    int re_search();
  475. #endif
  476.  
  477. #if !defined(__STDC__) || __STDC__ <= 0
  478. #define volatile
  479. #endif
  480.  
  481. /* Figure out what '\a' really is. */
  482. #ifdef __STDC__
  483. #define BELL    '\a'        /* sure makes life easy, don't it? */
  484. #else
  485. #    if 'z' - 'a' == 25    /* ascii */
  486. #        if 'a' != 97    /* machine is dumb enough to use mark parity */
  487. #            define BELL    '\207'
  488. #        else
  489. #            define BELL    '\07'
  490. #        endif
  491. #    else
  492. #        define BELL    '\057'
  493. #    endif
  494. #endif
  495.  
  496. #ifndef SIGTYPE
  497. #define SIGTYPE    void
  498. #endif
  499.  
  500. extern char casetable[];    /* for case-independent regexp matching */
  501.